﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace CPPEI.Coolzon.Designer.Views
{
    public enum MarksLocation
    {
        Up, Down
    }

    class RuleCtrl : FrameworkElement
    {
        public bool AutoSize
        {
            get
            { return (bool)GetValue(AutoSizeProperty); }
            set
            {
                SetValue(AutoSizeProperty, value);
                InvalidateVisual();
            }
        }
        public static readonly DependencyProperty AutoSizeProperty =
            DependencyProperty.Register(
                "AutoSize",
                typeof(bool),
                typeof(RuleCtrl),
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

        public double Length
        {
            get
            {
                if (AutoSize)
                    return (double)ActualWidth;
                else
                    return (double)GetValue(LengthProperty);
            }
            set
            {
                SetValue(LengthProperty, value);
            }
        }
        public static readonly DependencyProperty LengthProperty =
             DependencyProperty.Register(
                  "Length",
                  typeof(double),
                  typeof(RuleCtrl),
                  new FrameworkPropertyMetadata(20D, FrameworkPropertyMetadataOptions.AffectsRender));

        public double Zoom
        {
            get { return (double)GetValue(ZoomProperty); }
            set
            {
                SetValue(ZoomProperty, value);
                InvalidateVisual();
            }
        }
        public static readonly DependencyProperty ZoomProperty =
            DependencyProperty.Register(
            "Zoom",
            typeof(double),
            typeof(RuleCtrl),
            new FrameworkPropertyMetadata(100.0, FrameworkPropertyMetadataOptions.AffectsRender));

        public MarksLocation Mark
        {
            get { return (MarksLocation)GetValue(MarkProperty); }
            set { SetValue(MarkProperty, value); }
        }
        public static readonly DependencyProperty MarkProperty =
            DependencyProperty.Register(
            "Mark",
            typeof(MarksLocation),
            typeof(RuleCtrl),
            new FrameworkPropertyMetadata(MarksLocation.Up, FrameworkPropertyMetadataOptions.AffectsRender));

        public Brush MarksBrush
        {
            get { return (Brush)GetValue(MarksBrushProperty); }
            set { SetValue(MarksBrushProperty, value); }
        }
        public static readonly DependencyProperty MarksBrushProperty =
            DependencyProperty.Register(
            "MarksBrush",
            typeof(Brush),
            typeof(RuleCtrl),
            new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.AffectsRender));

        public int CountShift
        {
            get { return (int)GetValue(CountShiftProperty); }
            set { SetValue(CountShiftProperty, value); }
        }
        public static readonly DependencyProperty CountShiftProperty =
             DependencyProperty.Register("CountShift", typeof(int), typeof(RuleCtrl),
                  new FrameworkPropertyMetadata(0,
                        FrameworkPropertyMetadataOptions.AffectsRender));


        public int Interval
        {
            get { return (int)GetValue(IntervalProperty); }
            set { SetValue(IntervalProperty, value); }
        }
        public static readonly DependencyProperty IntervalProperty =
             DependencyProperty.Register("Interval", typeof(int), typeof(RuleCtrl),
                  new FrameworkPropertyMetadata(5,
                        FrameworkPropertyMetadataOptions.AffectsRender));

        public RuleCtrl()
        {
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            if (Mark == MarksLocation.Up)
                drawingContext.DrawLine(new Pen(MarksBrush, 1), new Point(0, 0), new Point(Length, 0));
            else
                drawingContext.DrawLine(new Pen(MarksBrush, 1), new Point(0, ActualHeight), new Point(Length, ActualHeight));
            int curPixel = CountShift;
            while (curPixel % Interval != 0)
                curPixel++;
            DrawLine(curPixel, drawingContext);
            curPixel += Interval;
            while ((curPixel - CountShift) < Length / Zoom * 100)
            {
                DrawLine(curPixel, drawingContext);
                curPixel += Interval;
            }
        }
        private void DrawLine(int curPixel, DrawingContext drawingContext)
        {
            FormattedText ft = new FormattedText(
                        (curPixel).ToString(CultureInfo.CurrentCulture),
                         CultureInfo.CurrentCulture,
                         FlowDirection.LeftToRight,
                         new Typeface("Arial"),
                         Height * 3 / 10,
                         Brushes.DimGray);
            ft.SetFontWeight(FontWeights.Bold);
            ft.TextAlignment = TextAlignment.Center;
            Pen pen = new Pen(MarksBrush, 1);
            if (Mark == MarksLocation.Up)
            {
                if (curPixel % (Interval * 10) == 0)
                {
                    drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, 0), new Point((curPixel - CountShift) * Zoom / 100, Height * 3 / 5));
                    drawingContext.DrawText(ft, new Point((curPixel - CountShift) * Zoom / 100, (Height - ft.Height)));
                    return;
                }
                if (curPixel % (Interval * 5) == 0)
                {
                    drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, 0), new Point((curPixel - CountShift) * Zoom / 100, Height * 2 / 5));
                    return;
                }
                drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, 0), new Point((curPixel - CountShift) * Zoom / 100, Height / 4));
            }
            else
            {
                if (curPixel % (Interval * 10)  == 0)
                {
                    drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, Height * 2 / 5), new Point((curPixel - CountShift) * Zoom / 100, Height));
                    drawingContext.DrawText(ft, new Point((curPixel - CountShift) * Zoom / 100, 0));
                    return;
                }
                if (curPixel % (Interval * 5) == 0)
                {
                    drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, Height * 3 / 5), new Point((curPixel - CountShift) * Zoom / 100, Height));
                    return;
                }
                drawingContext.DrawLine(pen, new Point((curPixel - CountShift) * Zoom / 100, Height * 3 / 4), new Point((curPixel - CountShift) * Zoom / 100, Height));
            }
        }
    }
}
